<!DOCTYPE html>
<html lang="en">
	<head>
		<title>three.js webgl - loaders - Rhino 3DM loader</title>
		<meta charset="utf-8">
		<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
		<link type="text/css" rel="stylesheet" href="main.css">
		<style>
			#loader {
				border: 5px solid #f3f3f3; /* Light grey */
				border-top: 5px solid #3d3d3d; /* Grey */
				border-radius: 50%;
				width: 40px;
				height: 40px;
				animation: spin 1s linear infinite;
				position: absolute;
				top: 50%;
				left: 50%;
				z-index: 2;
			}

			@keyframes spin {
				0% { transform: rotate(0deg); }
				100% { transform: rotate(360deg); }
			}
		</style>
	</head>

	<body>
		<div id="info">
			<a href="https://threejs.org" target="_blank" rel="noopener">three.js</a> - Rhino 3DM loader
		</div>

		<div id="loader"></div>
		<script type="importmap">
			{
				"imports": {
					"three": "../build/three.module.js",
					"three/addons/": "./jsm/"
				}
			}
		</script>

		<script type="module">

			import * as THREE from 'three';

			import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
			import { Rhino3dmLoader } from 'three/addons/loaders/3DMLoader.js';

			import { GUI } from 'three/addons/libs/lil-gui.module.min.js';

			let camera, scene, renderer;
			let controls, gui;

			init();

			function init() {

				THREE.Object3D.DEFAULT_UP.set( 0, 0, 1 );

				renderer = new THREE.WebGLRenderer( { antialias: true } );
				renderer.setPixelRatio( window.devicePixelRatio );
				renderer.setSize( window.innerWidth, window.innerHeight );
				renderer.setAnimationLoop( animate );
				document.body.appendChild( renderer.domElement );

				camera = new THREE.PerspectiveCamera( 60, window.innerWidth / window.innerHeight, 1, 1000 );
				camera.position.set( 26, - 40, 5 );

				scene = new THREE.Scene();

				const directionalLight = new THREE.DirectionalLight( 0xffffff, 6 );
				directionalLight.position.set( 0, 0, 2 );
				scene.add( directionalLight );

				const loader = new Rhino3dmLoader();
				//generally, use this for the Library Path: https://cdn.jsdelivr.net/npm/rhino3dm@8.0.1
				loader.setLibraryPath( 'jsm/libs/rhino3dm/' );
				loader.load( 'models/3dm/Rhino_Logo.3dm', function ( object ) {

					scene.add( object );
					initGUI( object.userData.layers );

					// hide spinner
					document.getElementById( 'loader' ).style.display = 'none';

				}, function ( progress ) {

					console.log( ( progress.loaded / progress.total * 100 ) + '%' );

				}, function ( error ) {

					console.log( error );

				} );

				controls = new OrbitControls( camera, renderer.domElement );

				window.addEventListener( 'resize', resize );

			}

			function resize() {

				const width = window.innerWidth;
				const height = window.innerHeight;

				camera.aspect = width / height;
				camera.updateProjectionMatrix();

				renderer.setSize( width, height );

			}

			function animate() {

				controls.update();
				renderer.render( scene, camera );

			}

			function initGUI( layers ) {

				gui = new GUI( { title: 'layers' } );

				for ( let i = 0; i < layers.length; i ++ ) {

					const layer = layers[ i ];
					gui.add( layer, 'visible' ).name( layer.name ).onChange( function ( val ) {

						const name = this.object.name;

						scene.traverse( function ( child ) {

							if ( child.userData.hasOwnProperty( 'attributes' ) ) {

								if ( 'layerIndex' in child.userData.attributes ) {

									const layerName = layers[ child.userData.attributes.layerIndex ].name;

									if ( layerName === name ) {

										child.visible = val;
										layer.visible = val;

									}

								}

							}

						} );

					} );

				}

			}
		</script>

	</body>
</html>
